package br.uece.laconi.tac.fuzzy;

import br.uece.laconi.tac.fuzzy.functions.GenericFunction;

public class CrispFuzzyNumber extends FuzzyNumber {
	public float value;
	
	
	public CrispFuzzyNumber(final float value) {
		super(new GenericFunction() {
			public Float calculate(float[] var) {
				float x = var[0];
				return (x == value)?(1f):(0f);
			}
		});
		this.value = value;
		super.setInterval(value, value);
	}	

	public String toString() {
		return Float.toString(value);
	}
	
	@Override
	public FuzzyNumber dividedby(FuzzyNumber num) {
		if (num instanceof CrispFuzzyNumber) {
			CrispFuzzyNumber n = (CrispFuzzyNumber) num;
			return new CrispFuzzyNumber(value / n.value);			
		}
		return null;
	}

	@Override
	public FuzzyNumber minus(FuzzyNumber num) {
		if (num instanceof CrispFuzzyNumber) {
			CrispFuzzyNumber n = (CrispFuzzyNumber) num;
			return new CrispFuzzyNumber(value - n.value);			
		}
		return null;
	}

	@Override
	public FuzzyNumber plus(FuzzyNumber num) {
		if (num instanceof CrispFuzzyNumber) {
			CrispFuzzyNumber n = (CrispFuzzyNumber) num;
			return new CrispFuzzyNumber(value + n.value);			
		}
		return null;
	}

	@Override
	public FuzzyNumber times(FuzzyNumber num) {
		if (num instanceof CrispFuzzyNumber) {
			CrispFuzzyNumber n = (CrispFuzzyNumber) num;
			return new CrispFuzzyNumber(value * n.value);			
		}
		if (num instanceof TriangleFuzzyNumber) {
			TriangleFuzzyNumber n = (TriangleFuzzyNumber) num;
			return new TriangleFuzzyNumber(value*n.center, value*n.leftSpread, value*n.rightSpread);
		}
		return null;
	}

	public boolean greater(float d) {
		return value > d;
	}
	
	/* Functions representing the fuzzy linguistics terms:
	 * 
	 * 			| close_to  medium_to far_from
	 * 			|__________  ______  _________
	 * 			| 	       \'      '/
	 * 			|          /\      /\
	 * 			|         / '\    /' \       
	 * 			|        /  ' \  / '  \ 
	 * 			|_______/___'__\/__'___\______ 
	 *        		 0.5   0.8 1  1.2  1.5
	 */
	
	public FuzzySet closeToSet = new TrapezoidFuzzyNumber(new float[] {0.0f, 0.0f, 0.5f, 1.0f});
	public FuzzySet mediumToSet = new TrapezoidFuzzyNumber(new float[] {0.5f, 0.8f, 1.2f, 1.5f} );
	public FuzzySet farFromSet =  new TrapezoidFuzzyNumber(new float[] {1f, 1.5f, 100f, 100f} );
	
	public CrispFuzzyNumber closeTo(CrispFuzzyNumber num) {
		float d = Math.abs(this.value - num.value);
		float r = closeToSet.membershipDegree(d);
		return new CrispFuzzyNumber(r);
	}

	public CrispFuzzyNumber farFrom(CrispFuzzyNumber num) {
		float d = Math.abs(this.value - num.value);
		float r = farFromSet.membershipDegree(d);
		return new CrispFuzzyNumber(r);
	}

	public CrispFuzzyNumber mediumTo(CrispFuzzyNumber num) {
		float d = Math.abs(this.value - num.value);
		float r = mediumToSet.membershipDegree(d);
		return new CrispFuzzyNumber(r);
	}
	
	public CrispFuzzyNumber AND(CrispFuzzyNumber num) {
		return and(num);
	}
	
	public CrispFuzzyNumber and(CrispFuzzyNumber num) {
		return FuzzyOperations.and(this, num);
	}

	public CrispFuzzyNumber OR(CrispFuzzyNumber num) {
		return or(num);
	}
	
	public CrispFuzzyNumber or(CrispFuzzyNumber num) {
		return FuzzyOperations.or(this, num);
	}
	
	@Override
	public CrispFuzzyNumber is(FuzzySet set) {
		return (new CrispFuzzyNumber(set.membershipDegree(this.value)));
	}
}
